home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-09-28 | 47.2 KB | 1,198 lines | [TEXT/KAHL] |
- About CDEF's…
-
- If you have downloaded previous versions of this package,
-
- READ THE REVISION HISTORY AT THE BOTTOM OF THIS DOCUMENT
-
- some minor but important details have changed !!
-
- Here is a collection of 10 CDEF's (Control Definitions) and some bits of
- source code to demo their use.
-
- procID Name Function
- ------ ----------- --------------------------------------------------------
- 100 GroupBox draws a titled box, text in upperleft
- 101 PopUp Menu system 7 style popup menu control
- 102 Spinner "little arrows" control
- 103 Date & Time Date & Time control using "little arrows"
- 104 Tog Button a new type of "one or many" control
- 105 HSlider horizontal slider control
- 106 VSlider vertical slider control
- 107* 3D Buttons a 3d replacement for the standard button CDEF
- 108 Progress Bar a progress bar CDEF
- 109 TabPanel a "Tab Panel" control as in MSWord
-
- * this CDEF has been renumbered to 0 in the xDEF.rsrc file
- --------------------------------------------------------------------------------
-
- The source code for all of the CDEF's is not included here, but you can find
- the CDEF's as code resources in file xDEF.rsrc.
-
- (If you are new to Mac programming, CDEF's are code resources that can just
- be pasted into your project's resource file and used by your programs).
-
- The source for the "3D Buttons" CDEF is included, along with some utility
- routines common to all of the CDEF's. A test harness to allow source level
- debugging is also included.
-
- I have not decided if I will upload the source for the rest of the CDEF's.
- I keep tweaking them at this point (a coding job is never finished) and the
- full source & projects is rather large.
-
- This file is getting pretty long, it is divided into the following sections:
-
- - Introduction
- - Control Descriptions
-
- CDEF details
- - Variation codes & control size
- - Non-standard control RefCon usage
- - Non-standard control template usage
-
- General information
- - Using custom controls in a dialog
- - Using custom controls in a window
- - Colorizing Controls & Dialogs
- - Changing the font in a Dialog
-
- - About "TogButtons"
- - About Tab Panels
- - Revision history
-
- Jim Stout
-
- September 1994
-
- I can be reached electronically at:
-
- Internet : JimS@WRQ.COM (work hours, PST)
- AppleLink : WRQ (daily)
- CompuServe : 73240,2052 (weekly or so)
- AOL : JasG (weekly or so)
- --------------------------------------------------------------------------------
-
- The source & executable code may be freely redistributed as long as all of the
- original package is included AND no specific charge is made for the package.
-
- The CDEF's or other code in this package may be incorporated in any freeware,
- shareware, commercial or other software package.
-
- --------------------------------------------------------------------------------
- Introduction
- ============
-
- A few weeks back I was reading the Human Interface volume of Inside Mac and it
- struck me as funny that Apple refers to various controls (used throughout the
- MacOS) as "not supported by the Toolbox". Controls like "little arrow"
- controls used to set Date & Time, Memory etc., "Slider Controls" like those in
- the Sound or Brightness control panels and a "Progress Bar" are simply are not
- to be found in the Toolbox.
-
- Apple simulates controls by displaying appropriate PICT's and handling mouse
- events in a dialog filter (I think).
-
- I realized that over the past couple of years, I had written some of those
- controls (the rest are hot off my coding pad).
-
- Two of the CDEF's, 104 "Tog Button" and 109 "TabPanel" are a little different.
- This is explained below in the sections "About Tog Buttons" and "About Tab
- Panels.
-
- Most of these controls will work with System 6 or System 7 - the only caveats
- are:
-
- - PopUpMenu control requires PopUpMenuSelect.
- - TabPanel control requires AppendDITL etc. (System 6 with CTB or System 7)
- - 32bit ColorQuickdraw v1.2 is required for any of the controls to draw
- "3D" variants and to use use the System 7 style gray when disabled.
-
- I have tested them on machines from a MacPlus through a PowerMac 7100.
- (Actually, I've tested these as far back as System 3.2 - I've gotta do
- something with that original 128k Mac with MacPlus ROM's that is sitting in
- the corner...)
-
- All controls with titles honor the "useWindFont" variation code (to draw in a
- non-System font) and if possible, the controls will honor control colors found
- in 'cctb' resources.
-
- The "3D Buttons" and "TabPanel" CDEFS will always use a "3D" effect if the
- background color is non-white AND the control can draw itself in color.
- This behavior cannot be overridden for these controls. Sorry.
-
- As far as I can tell, the controls all handle low memory situations by
- refusing to draw themselves. Let me know if you see any problems.
-
- I have not written these to support non-roman script systems.
-
- Other variation codes, sizes and non-standard control template values are
- listed below.
-
- --------------------------------------------------------------------------------
- Control Descriptions
- ====================
-
- Common features:
-
- - color per 'cctb' resources.
- - disable with "GrayishTextOr" effect under System 7.
- - have an embossed, 3D variation.
- - respect the "useWindFont" variation code (8).
- - All control drawing is clipped to the control rect, so it should be
- pretty obvious if you have a control rect that is too small.
-
- NOTE: all controls rely on a private data structure stored in
- the contrlData field of the control structure. Don't
- use this field for your own use or unpredictable things
- will happen.
-
- Also, some of the controls look at the value of the refCon when
- initializing to get some extra parameters.
-
- If you want to place a value in the refCon for your program's use,
- don't set it until AFTER you call NewControl or NewDialog and
- the controls have been initialized. (The DateTime CDEF is a MAJOR
- exception - see below - it uses the refCon for its "value" field.)
-
- GroupBox
-
- This control is pretty simple. It frames the control rect and places
- the title in the upper left corner.
-
- It can be used to logically group a series of related controls.
-
- It does not respond to mouse clicks, it does have variation
- codes for a dashed-line frame and a 3D effect.
-
- To use this control, you have to play some games with the control
- rect to keep it from overlaying other controls. Essentially, you
- must set the control rect height to include ONLY the title and then
- specify the true height of the control in the contrlMax field.
-
- PopUp Menu
-
- This control was written to replace both the System 6 & 7 versions of
- the Apple CDEF 63. Apple's CDEF has some problems - it behaves
- differently under System 6 and 7, does not respect 'mctb' (menu
- color) resources for menu items.
-
- The handle stored in the contrlData field is as documented by Apple
- and can be used to retrieve the MenuHandle of the the popup menu. See
- IM VI and the jimsCDEF.h file.
-
- Spinner
-
- This a control that "Apple never wrote". It allows for adjustment of
- a numeric value via "little" arrows.
-
- The default increment is 1, but this can be specified in the control
- template in the refCon field. The control value will increment in
- a "ballistic" manner - as the mouse button is held down, the increment
- value will increase from 1 to 10 to 100.
-
- This CDEF can be "linked" to a dialog edit text item to update.
-
- CDEFs cannot get keyDown events, so the trick here is to have the
- CDEF update the edit text item. To do this, set the HiWord of
- control refCon to a DITL editText item number to be updated. In
- this case, set the LoWord of the refCon to the desired increment.
-
- The calling program must take care of insuring that only digits
- are typed into the edit text. ALSO, when the user types new
- digits, the calling program must get the contents of the edit item,
- convert it to a number and call SetCtlValue to let the control
- know about the new value. Otherwise, the next click in the
- control will wipe out the typed value.
-
- The handle stored in the contrlData field is documented in the
- jimsCDEF.h file. There is a "userData" field for your use.
-
- PartCodes returned via TrackControl are :
- 2 - in up arrow
- 3 - in down arrow
-
- (the control will have updated its value when TrackControl returns)
-
- Date & Time
-
- This is a control to adjust Date and/or Time values. Clicking on
- a time or date component (month, hours, etc.) will hilite
- those digits and show "little" arrows that can be used to adjust
- the date or time value.
-
- Variation codes can specify display of Date, Time, both, horizontal
- or vertical display. The m/d/y order of the date will match what
- the user has set in the Date & Time control panel. Leading zeros
- are always drawn - it makes things a lot simpler for the CDEF.
-
- Likewise, 12 or 24 hour time is taken from the system settings. To
- force a 24 hour setting, pass a non-zero contrlMax in the control
- template. To get a "3D" effect for the control title and arrows,
- pass a non-zero contrlMin in the control template.
-
- The "value" of the control is a DateTimeRec. Since this is a long,
- it is stored in the contrlRfCon field, NOT in the contrlValue field
- of the control record. So, rather than using GetCtlValue(), use
- GetCRefCon() to access the control value.
-
- There is no keyboard handling for setting date & time. CDEF's do
- not have any mechanism for keyboard events. I think that this could
- be done from a user program, but I'll leave that as an exercise for
- those that need it.
-
- (Hint, the contrlValue is always the hilited digits field and you can
- change the date & time shown by the control by setting a new DateTimeRec
- into the control RefCon and drawing the control.)
-
- Resetting the date and time requires the following:
-
- GetDateTime(&secs);
- SetCRefCon(hCtrl, secs);
- InvalRect(&(**hCtrl).contrlRect);
-
- Tog Button
-
- This is explained in great detail below.
-
- A "Tog" button is a diamond shaped control, a mix of CheckBox and
- Radio button behavior. A group of these controls can have many
- "on" members (like a checkbox), but must always have one member
- that is "on" (like a radio button).
-
- This file requires use of some support routines in TogLib.c that
- must be called by your program.
-
- Variation code 4 in the 3D Buttons control will have the same
- result.
-
- HSlider
-
- This is an exact duplicate of the slider control in the Brightness
- Control Panel.
-
- Several variation codes are available to alter the appearance of
- the control. See below or the demo program.
-
- This and the VSlider control will call back to an "actionProc" if
- one is set via SetCtlAction() and you call TrackControl with -1 as
- the last parameter. This could be used to implement a "live"
- display of the control value as the thumb is dragged around.
-
- Part codes returned to TrackControl are :
- 1 - in "thumb"
- 2 - in "decrease"
- 3 - in "increase"
-
- VSlider
-
- This is an exact duplicate of the slider control in the Sound
- Control Panel.
-
- Several variation codes are available to alter the appearance and
- behavior of the control. See below or the demo program.
-
- See notes above for "actionProc" & TrackControl issues.
-
- 3D Buttons
-
- Source is included for this control.
-
- This is a replacement for the standard CDEF 0 (which supplies
- controls for check boxes, radio buttons, push buttons). An
- addition is variation code 4 - in this control it supplies a
- "Tog" button.
-
- It provides 3D equivalent to the standard controls. The push
- button variation is a square edged, raised button. Text is
- "embossed".
-
- Progress Bar
-
- This is a control to provide a "thermometer" or "barber pole"
- indicator. It can be used to display the progress of a long
- running operation (like the thermometer in the "Copying file…"
- alert. The "barber pole" variation can be used when the
- operation is proceeding, but the end point is not known - like
- searching for a series of files.
-
- Variation codes can be used for horizontal, vertical, rectangular,
- oval or barber pole indicators.
-
-
- TabPanel
-
- This too, is explained in great detail below.
-
- This is a problematic control. It will be too "Windows-like" for
- many. I wrote it to see if it could be done on the Mac after seeing
- what a co-worker was doing. Don't use it if you don't like it.
-
- It draws a box with a series of "tabs" long the top edge, like At Ease
- in some respects. It could be used to provide a dialog with multiple
- "panels" - like the Think Project Manager "Options" dialog which uses
- a popup to switch panels, or many CommToolbox tools which use a list
- of icons.
-
- Clicking on a "tab" will change the control value. Your program can
- then change the other controls on the panel - either by hiding/showing
- controls or using ShortenDITL/AppendDITL calls.
-
- To use this control, you have to play some games with the control
- rect to keep it from overlaying other controls. Essentially, you
- must set the control rect height to include ONLY the tab titles and
- then specify the true height of the control in the contrlMin field.
-
- --------------------------------------------------------------------------------
- CDEF details
- --------------------------------------------------------------------------------
-
- See file jimsCDEF.h for #defines for variation codes and structs for private
- data for Spinner & Popup menu CDEFs.
-
- Variation codes & control size
- ==============================
-
- (min h & w is minimum required height & width for the control rect
- when using Chicago 12 font)
-
- CDEF varCode min h & w Result
- --------- ---------- ---------- --------------------------------------------
- GroupBox 0 16 x nn Draws a solid frame
- 1 Draws a dotted frame
- 2 3D effect
- 4 * not used *
- 8 Use the Window font for title
-
- NOTE: To avoid problems with "layering" of this control over or
- under the contents of a box, set the height of this control
- to 16 or so, then put the height you REALLY want in the
- contrlMax field of the CNTL template. The control rect
- (used by the Dialog Manager) will not obstruct other controls.
- However, when the control draws - it will use the height value
- from the contrlMax field.
-
- Uses cFrameColor & cTextColor from 'cctb'
-
- --------------------------------------------------------------------------------
- PopUp Menu 19 x nn (see IM VI or docs for Apple CDEF 63
- 19 x 25 for "triangle only" menu
- 1 use fixed width for menu
- 2 3D effect
- 4 use RefCon for AddResMenu
- 8 Use the Window font for title & menu
- NOTE: if the menu has styled text items, the height may need to be
- greater than 19.
- Unlike the Apple CDEF 63, this control will:
- - behave the same with System 6 & 7
- - properly handle colored menus
- It DOES NOT support:
- - Icons or cmd keys
- - Styled text titles
-
- Uses cTextColor for title and colors from 'mctb' for menu.
-
- --------------------------------------------------------------------------------
-
- Spinner 0 18 x nn Small, as in "Date & Time" Control panel
- 1 25 x nn Large, as in "Memory" Control panel
- 2 3D arrows
- 4 * not used *
- 8 Use the Window font for drawing
-
- NOTE: use 18 x 11 or 25 x 15 to get arrows only.
- 3D arrows are colored, as are system scroll bars, with
- with cTingeLight & cTingeDark.
-
- --------------------------------------------------------------------------------
-
- Date & Time 0 18 x 160 Date left, Time right justified
- 1 18 x 80 Date only, left justified
- 2 18 x 80 Time only, left justified
- 4 37 x 80 Both on 2 lines, date over time
- 8 Use the Window font for drawing
-
- NOTE: non-standard date or time separator characters may
- need a larger rect. Also, if a title is specified,
- the width of the control will need to be increased.
-
- Uses cFrameColor & cTextColor. 3D arrows colored
- with cTingeLight & cTingeDark.
-
- --------------------------------------------------------------------------------
-
- Tog Button 0 18 x nn Normal button title
- 1 * not used *
- 2 * not used *
- 4 * not used *
- 8 Use the Window font for title
-
- Uses cFrameColor & cTextColor from 'cctb'
-
- --------------------------------------------------------------------------------
-
- HSlider 0 24 x 121 As in the "Brightness" Control panel
- 1 Scale drawn in bg color (not filled)
- 2 Drawn with a 3D effect
- 4 Scale drawn in gray pattern
- 8 * not used *
-
- Uses cFrameColor & cTextColor from 'cctb'
-
- --------------------------------------------------------------------------------
-
- VSlider 0 105 x 42 As in the "Sound" Control panel
- 1 Scale drawn in bg color (not filled)
- 2 Drawn with a 3D effect
- 4 "Thumb" will not "snap" to tick mark
- 8 Scale is blank, no numbers, no marks
-
- NOTE: ht is 12*divisions + 21 (see below)
- Uses cFrameColor & cTextColor from 'cctb'
-
- --------------------------------------------------------------------------------
-
- 3D Buttons 0 any x any draws a push button
- 1 draws a checkbox
- 2 draws a radiobutton
- 4 draws a Tog Button control
- 8 Use the Window font for title
-
- NOTE: This control should behave just like the standard CDEF 0 when
- running in 1 bit (B&W) mode OR if the background is white. If
- running on a non-white background, this CDEF will draw "3 D"
- controls.
-
- Uses cFrameColor & cTextColor from 'cctb'. Gray shading is a
- gray that is intermediate to the background color & cFrameColor.
-
- --------------------------------------------------------------------------------
-
- Progress Bar 0 any x any draws a horizontal progress bar
- 1 draws a vertical progress bar
- 2 draws a rounded, 3D progress bar
- 4 draws a "Barber Pole" progress bar
- 8 not used
-
- NOTE: to get a "Barber Pole" variation to work, you need to call
- it with a different value each time. Simply setting min=0
- and max=1, then setting its value to 0, then 1, then 0 etc.
- inside your loop operation will work.
-
- 'cctb' resource entries for cFillPat and cTingeLight are used
- to color this control.
-
- --------------------------------------------------------------------------------
-
- Tab Panel 0 20 x nn draws a "Tab Panel", uses Geneva 9
- for tab titles.
- 1 Use System font for tab titles.
- 2 Force a single panel (1 row of tabs).
- 8 Use the Window font for tab titles.
-
- NOTE: To avoid problems with "layering" of this control over or
- under the contents of a box, set the height of this control to
- 16 * rows, then put the height you REALLY want in the contrlMin
- field of the CNTL template. The control rect (used by the
- Dialog Manager) will not obstruct other controls. However,
- when the control draws - it will use the height value from the
- contrlMin field.
-
- Uses cFrameColor & cTextColor from 'cctb'. Gray shading is a
- gray that is intermediate to the background color & cFrameColor.
-
- --------------------------------------------------------------------------------
-
- Non-standard control RefCon usage
- ===================================
-
- Note: Several of these controls use the control refcon field. They are:
-
- PopUp Menu - use of refcon is identical to Apple's CDEF 63
- - not used by control after initialization.
-
- Spinner - refcon may be used to indicate an "increment" value. Also,
- you can set both an increment and a DITL item (for an edit
- text item to update). See below.
- - the increment value is limited to 1-1000 and the DITL item
- number must be 0-100.
- - not used by control after initialization.
-
- VSlider - refcon may be used to indicate the number of divisions
- but will default to 7 divisions. Must be in the range
- 2-20.
- - not used by control after initialization.
-
- DateTime - refcon is the "value" of the control. It is updated
- by the control.
- - ** USED ** by control after initialization - see below.
-
- Tab Panel - refcon is a "right margin". If zero, tabs will fill
- the entire width of the control. This value must be
- between 0 and control width/2.
- - not used by control after initialization.
-
- --------------------------------------------------------------------------------
-
- Non-standard control template usage
- ===================================
-
- GroupBox does not use min, value or rfCon. max is used for the
- true height of the control.
-
- Rect should be set to 16 pixels, just enough for the title.
-
- PopUp Menu (see Inside Mac VI or other docs for Apple CDEF 63)
- Briefly:
-
- procId : 1616 + varCode (101 * 16) + varCode
- : varCodes
- popupFixedWidth = 0x0001
- ctl3D = 0x0002
- popupUseAddResMenu = 0x0004
- popupUseWFont = 0x0008
-
- value : title justification
- : popupTitleLeftJust = 0x00000000
- : popupTitleCenterJust = 0x00000001
- : popupTitleRightJust = 0x000000FF
-
- min : resId of menu to use, even if using
- popupUseAddResMenu, it is best to have a
- 'dummy' menu resource with no items defined.
-
- max : width of title item - from controlRect.left
- : 0 = no title drawn.
- : -1 = draw 'popUp symbol' only
-
- refCon : if varCode of popupUseAddResMenu, put the
- ResType in the refCon field of the control.
-
- Does NOT support menu icons or cmd-keys, the menu
- can have them, but the control will not draw them.
-
- Spinner standard use of min, max and value.
-
- The control refCon field can be set to a long word
- that indicates both the increment to use and a DITL
- item to update (optional).
-
- LOWORD = increment value (default increment is 1)
- HIWORD = DITL item number for an editText item to
- update with the control value.
-
- Date & Time max - if non-zero, reverse 12/24 hour setting.
- min - if non-zero, draw "3D" control.
-
- contrlValue indicates hilited digits
- 1 hours
- 2 minutes
- 3 AM/PM
- 7 month (7,8,9 match user order from Control Panel
- 8 day and may not have these meanings)
- 9 year
-
- contrlRfCon is seconds as passed to GetDateTime(),
- Secs2Date() and Date2Secs() calls. This is the "value"
- that the control adjusts. Use GetCRefCon() to retrieve
- the "date time" value and SetCRefCon() to set it.
-
- HSlider min = 0, max = 100 - these are set by the control.
-
- value returned will range from 0 to 100
-
- VSlider refCon is used to indicate 'number of divisions' from
- 2-20. Default is 7 divisions with tick marks from 0-7.
- min = 0
- max = 12*"number of divisions"
-
- The value returned will range from 0 to max.
-
- The control "thumb" will "snap" to a tick mark.
- This means that the value will always be 12*tick mark.
-
- To avoid the "snap" behavior, use varCode 4.
-
- 3D Buttons standard use of all fields, but with an
- additional variation code for "Tog" buttons.
-
- Progress Bar standard use of all fields.
-
- Control cannot be disabled.
-
- Tab Panel min = true height of the control.
- max = number of tabs
- value = "active" tab. Title is bold.
- title = one per tab, separated by CR (0x0d)
- refCon = right margin - no tabs drawn in this area.
-
- Rect should be set to #rows * 16 pixels, just enough for
- all rows of tabs.
-
- Control cannot be disabled.
-
- --------------------------------------------------------------------------------
-
- Using custom controls in a dialog
- =================================
-
- To use custom controls in a dialog, it is important to understand the
- interaction between the Dialog Manager, Control Manager and resource
- definitions for dialogs.
-
- Underlying all controls in a Macintosh window (dialog or other) is the Control
- Manager. Fundamental to this is the Toolbox call to create a new control:
-
- ControlHandle ch;
-
- ch = NewControl(
- theWindow, the window the control belongs to
- *theRect, rectangle for control
- title, title for control
- visible, initially visible or not
- initialValue, control value
- min, minimum value
- max, maximum value
- ctrlType, 16*procID+variation code
- refCon user specified value
- );
-
- ctrlType is an important value and an understanding of its use if key to the
- use of custom controls. The procID is the resource id of a code resource of
- type 'CDEF'. Built into the Macintosh system are 'CDEF' resources of id 0 and
- 1 (and others). The 'CDEF' with procID=0 is used for push buttons, check boxes
- and radio buttons - with variation codes of 0, 1 and 2 respectively.
-
- So, to create buttons in a window, you could use NewControl and specify:
-
- = 16*procID+variation code
- --------------------------
- Push Button : ctrlType = 16*0+0 = 0
- Check Box : ctrlType = 16*0+1 = 1
- Radio Button : ctrlType = 16*0+2 = 2
-
- A special variation code of useWindFont (8) can be used with many controls to
- change the font of the control.
-
- So, to use a custom control, you simply specify a procID of something other
- than 0. If you want to substitute a custom control (like the 3D Button CDEF)
- for the default CDEF id=0, include a CDEF with id=0 in your application's
- resource fork. This was done in the demo program (and in the xDEF.rsrc file).
-
- Items in a dialog are specified in resource description files (.r files) using
- a syntax unique to your resource compiler. A dialog resource is composed of a
- 'DLOG' resource and a corresponding 'DITL' resource. The 'DLOG' resource
- defines the dialog itself, while the 'DITL' resource defines the item list for
- the dialog. A typical item description in a 'DITL' source file might be:
-
- resource 'DITL' (128) {
- /* Control Rect, ctrlType, flag, title */
- /* --------------------- ----------- --------- --------------- */
- {249, 396, 269, 455}, Button { enabled, "OK" },
- {249, 324, 269, 383}, Button { enabled, "Cancel" },
- {52, 22, 68, 142}, CheckBox { enabled, "Check box" },
- {76, 22, 92, 142}, RadioButton { enabled, "Radio button" }
- };
-
- For some standard controls (push buttons, radio buttons etc.), there are
- special 'DITL' definitions, as shown above. The Dialog Manager reads the
- information in the 'DITL' resource, fills in some default values and calls
- NewControl(). (The 'enable' flag is not really a parameter to NewControl(),
- but sets the contrlHilite field in the control record.)
-
- This means that you don't have to fill in the entire parameter list for
- NewControl() to have a control in a dialog - for the standard controls.
-
- If you want to use the useWindFont variation code or a custom control in a
- dialog, there is some extra work to do… You must define a special type of
- 'DITL' item, "Control" instead of "Button" etc. and then you must provide a
- matching resource of type 'CNTL'. The Dialog Manager will recognize this type
- of 'DITL' item and read the 'CNTL' resource to get some of the parameters it
- will use in the call to NewControl().
-
- The 'CNTL' resource contains fields for all of the parameters needed by
- NewControl(). In the example below, the DITL is changed to add the useWindFont
- variation to the items shown above, the resource description would look like:
-
- resource 'DITL' (128) {
- /* Control Rect, ctrlType, flag, 'CNTL' id */
- /* --------------------- ----------- --------- --------------- */
- {249, 396, 269, 455}, Control { enabled, 128 },
- {249, 324, 269, 383}, Control { enabled, 129 },
- {52, 22, 68, 142}, Control { enabled, 130 },
- {72, 22, 88, 142}, Control { enabled, 131 }
- };
-
- /* Control Rect initValue visFlag max min ctrlType refCon Title */
-
- resource 'CNTL' (128, purgeable) {
- {52, 22, 68, 142}, 0, visible, 1, 0, 16*0+8, 0, "OK"
- };
- resource 'CNTL' (130, purgeable) {
- {52, 22, 68, 142}, 0, visible, 1, 0, 16*0+8, 0, "Cancel"
- };
- resource 'CNTL' (130, purgeable) {
- {52, 22, 68, 142}, 0, visible, 1, 0, 16*0+1+8, 0, "Check box"
- };
- resource 'CNTL' (131, purgeable) {
- {72, 22, 88, 142}, 0, visible, 1, 0, 16*0+2+8, 0, "Radio button"
- };
-
- ** IMPORTANT **
-
- There are TWO rectangle definitions here - one in the 'DITL' and
- one in the 'CNTL'. If they don't match, your custom control may
- not draw, or it will flicker and seem to move when you first
- show the dialog. Also, clicks in the DITL rect may not be
- recognized by the Control when its rect is different.
-
- Make sure the rects match.
-
- If you use a resource editor instead of .r files & a resource compiler, you can
- define the 'DITL' and matching 'CNTL' resources directly. Resorcerer does a
- fine job at this. ResEdit is a bit more difficult to use.
-
- ResEdit does not keep the 2 rectangles in sync, if you drag a 'DITL' item
- around, the corresponding 'CNTL' is not updated.
-
- To use ResEdit, open the 'DITL' window and define a new item of type "Control"
- from the floating palette. Double click on the new item and fill in the
- resource id and rectangle information. Move this window aside, but so that you
- can still see the rect info.
-
- Now, hold down the command+option keys and double click on the item in the
- 'DITL' window. This brings up the 'CNTL' window where you can fill in the
- info for the 'CNTL' resource - fill in the "Bounds Rect" (top, left, bottom,
- right) item to match the rect in the 'DITL' window.
-
-
- --------------------------------------------------------------------------------
- Using custom controls in a normal window
- ========================================
-
- In some ways, it is easier to use a control in a normal window than in a dialog.
- BUT, you have to do mouseDown event processing since the Dialog Manager is not
- doing it for you.
-
- This is simple and identical to handling scroll bars or buttons in a window. Just
- call FindControl to determine where & if the mouse was clicked in a control, then
- call TrackControl. The code is nothing special, it looks like this:
-
- mousePt = theEvent->where;
- GlobalToLocal(&mousePt);
- partCode = FindControl(mousePt, theDialog, &controlHdl);
- if(partCode && controlHdl) {
- TrackControl(cHdl, mousePt, (ProcPtr)myTrack);
- }
-
- The only special things about these controls have to do with the last parameter to
- TrackControl - the actionProc. Normally, you can simply take the default
- and pass nil as the last parameter.
-
- Exceptions are:
-
- Popup Menu
- ----------
- You must pass (ProcPtr)-1 to tell the CDEF to "autoTrack".
-
- Spinner
- -------
- You may define an actionProc which will be called when the mouse is
- clicked in an arrow. Unlike a scrollBar, the Spinner CDEF will update
- its control value. So in your action proc, you can call GetCtlValue to
- obtain the current control value and do something with it (like stuff it
- in an edit text record or display it).
-
- Sliders
- -------
- Sliders don't really need an actionProc, you can call TrackControl with
- a nil actionProc and the slider will work just fine.
-
- If you want to implement a "live" display of the value of a slider control,
- you simply define an actionProc, but use SetCtlAction to tell the control
- to call it as the "thumb" of the slider is being dragged. (You still need
- to call TrackControl though, or the control will not respond to clicks
- in the scale portion of the control).
-
- In your actionProc, you can then call GetCtlValue to obtain the control
- value and display it.
-
- For the rest of the CDEF's, simply call TrackControl with a nil action proc
- (unless you want to extract the control value and do something with it each
- time the mouse is clicked in the control - then you must define an actionProc).
-
- --------------------------------------------------------------------------------
- Colorizing Controls & Dialogs
- --------------------------------------------------------------------------------
-
- The key to having a colored dialog is to include a 'dctb' (or 'actb' for Alerts)
- with the same ID as the 'DLOG' or 'ALRT' resource.
-
- For controls, there is a similar resource, a 'cctb'. Either create 'cctb'
- resources for each 'CNTL' resource, or to color ALL controls in an application,
- create a 'cctb' with ID=0.
-
- For the controls that have a "3D" variant, make sure you define the
- cTingeLight and cTingeDark colors in your 'cctb' or you won't get a nice
- looking control.
-
- See demoCDEF.r for examples.
-
- --------------------------------------------------------------------------------
- Changing the font in a Dialog
- --------------------------------------------------------------------------------
-
- Before showing your dialog (but after creating it), simple calls to:
-
- TextFont(geneva) and
- TextSize(9)
-
- will change the dialog font to Geneva 9. This WILL NOT WORK if you have an
- edit text item in the dialog or if you forget to specify the useWindFont
- variation for your controls.
-
- The best way to change the font for an edit item is to use 'ictb' resources, but
- these are a pain. Only Resorcerer does this well, Rez and ResEdit don't
- support 'ictb' resources.
-
- See demoCDEF.c for a crude hack that seems to work.
-
- --------------------------------------------------------------------------------
- About "TogButtons"
- --------------------------------------------------------------------------------
- In early November 1991, I ran across an article in the October 1991 "Apple
- Direct" by Bruce Tognazzini - Apple's human interface guru. Each month Tog
- would write a column dealing with HI issues. The article that caught my eye
- back then was titled "Case Study: One or more Buttons".
-
- I don't think that I can legally include Tog's article with this bit of code,
- but you can find it on many of the Apple Developer CD's in the
-
- Periodicals:Apple Direct:Apple Direct Oct '91:Tog folder.
-
- It also is in his book "Tog on Interface" as chapter 36.
-
- To summarize, Tog wrote about the design and usability testing of a new
- interface element that he called "One or more Buttons" - essentially a control
- that was part Checkbox and part Radio button. A group of Checkboxes can all be
- "Off" and a group of Radio buttons can only have one "On" value. What was
- needed was a group that MUST have ONE "On" control but could have many "On"
- controls - a "One or more Button".
-
- Tog's design for what I call "Tog Buttons" is a cross between a Radio button
- and a Checkbox. The control is a diamond (a Checkbox rotated 90 degrees) with
- a diamond shaped indicator (like the circular indicator in a Radio button).
- The behavior is also a cross between the two other controls. If only one
- control is ON, then clicking on it turns that control OFF and turns on an
- adjacent control (just like a pair of radio buttons), if one or more of the
- controls is ON, then others can be toggled (just like a checkbox).
-
- Another twist on the behavior is that if only one control is ON, a click on
- that control will turn if OFF, and turn on the one just above (or to the left
- of) it. When the first (or last) control is reached, the direction reverses,
- turning on the one just below (or to the right). Tog likened this behavior to
- that of a drop of mercury when you press on it with a finger (but without the
- toxicity!).
-
- The behavior is such that with a single ON button, clicking on just that
- button, causes it to "jump" up (or leftward). If you keep chasing the single
- ON button, it will keep "jumping" up until it must reverse direction and start
- "jumping" down. Unless you are "chasing" a button like this, when only one
- button is ON, the default behavior is to jump UP (or to the left). To see
- this, try the cdefDemo program and you will see what I mean.
-
- For some reason, this appealed to me as an interesting project and I spent a
- fun afternoon implementing Tog's idea. I ended up creating a CDEF to implement
- the control described by Tog and a couple of routines in C to support the
- desired behavior of "Tog Buttons".
-
- --------------------------------------------------------------------------------
- How to use a Tog Button in a dialog
- ===================================
-
- Obviously, using a Tog Button is only needed if you have a situation that has a
- group of items that requires "One or Many" values. An example might be a
- search :
-
- - Search -----------------
- | |
- | <•> C files (.c) |
- | < > Include files (.h) |
- | < > Resource files (.r) |
- | |
- --------------------------
-
- The file cdefDemo.c shows how to use "Tog Buttons", but here is a brief list.
-
- 1. Include the files TogLib.c/TogLib.h in your project.
-
- 2. Define the group of "Tog Buttons" in your dialog resource.
-
- 3. DITL item numbers MUST be successively numbered for each group of "Tog
- Buttons". This is IMPORTANT!
-
- 4. After calling GetNewDialog, but before calling ModalDialog, call
- initTogButtons() for each group of "Tog Buttons".
-
- 5. When a "Tog Button" is clicked, call setTogButtons() for that group of "Tog
- Buttons".
-
- 6. When a non-Tog Button control is clicked, do whatever is needed, then call
- resetTogButtons() for each group of "Tog Buttons". This step simply insures
- that the next click on a "Tog Button" will "go up".
-
- 7. Use regular calls to GetDItem() and GetCtlValue() to retrieve the control
- values for "Tog Buttons".
-
- The TogLib routines are the key to maintaining consistent behavior of the "Tog
- Buttons". TogLib.h has a short description of each routine.
- --------------------------------------------------------------------------------
- About Tab Panels
- --------------------------------------------------------------------------------
- Tab panels are what I call dialogs that use the TabPanel CDEF in this package.
-
- The CDEF is modeled after what I think is Microsoft's "Tabbed dialog" interface
- design. I think that this is being used in the new Mac versions of Word &
- Excel, but I haven't seen them yet.
-
- It could be used as an alternative to the common Mac approach of multi-panel
- dialogs that use a list of Icons to switch among several panels.
-
- This is doubtless a controversial interface element - even more so on the Mac.
- I don't condone it's use, I simply wanted to see if I could write a control
- like this.
-
- Think long and hard before you use this on the Mac - it may be rather foreign
- to Mac users and will take some thought. One of the biggest difficulties is
- "Where do the OK & Cancel buttons go?" and "What does a click on a tab mean?" -
- should changes be applied immediately, or wait for an OK on the dialog?
-
- If OK & Cancel are inside the "Tab" control, do you have to click on OK before
- changing tabs? How do you exit the dialog? Do you then need a "Done" button".
- Is a click on a tab the same as OK? and so on…
-
- If the OK and Cancel buttons are outside the "Tab" control, then do you need an
- "Apply" button that must be clicked or you loose changes if you switch panels
- by clicking on a new tab? Or is a click on a tab is that an implied
- acceptance of changes that will take effect when you click "OK"?
-
- There is some subtle but important stuff here. Think about it!
-
- Using the Tab Panel CDEF
- ------------------------
-
- You can specify from 1 to 20 tabs with this control (one would be silly and
- 20 is probably overkill). Tabs are presented with 4 per row by default, each
- tab is 1/4 of the width of the control. If you specify a tab count that is
- not a multiple of 4, the remaining tabs will be larger than the others so
- that the entire control width is occupied.
-
- The control max value indicates the number of tabs. The control title should
- contain a title for each tab, separated by a CR. If you want a "margin" on
- the right side with no tabs, put a "margin" value in the refCon field. The
- control rect height should be set to #rows * height of 1 tab. Then set the
- REAL height for the entire panel in the contrlMin field of the control
- template.
-
- The height of each row of tabs is calculated as : controlHeight/rows. 16 pixels
- per row is a good size. So, if you need 8 tabs, set the control rect to be
- 32 high.
-
- By default, this control will use a Geneva 9 font, with the "active" tab drawn
- as Bold. If you use the useWindFont variation code of 8, it will use the current
- font. A variation code of 1 will use the System font at all times, underlined
- instead of bold (IMHO, this looks better than bold Chicago 12).
-
- A variation code of 2 will force a single row of tabs, with as many tabs as
- specified by controlMax, each as wide as controlWidth/# tabs.
-
- If the background is not white, the control will draw as a "3D" control.
-
- Please note that the control cannot be disabled, nor can a single tab be disabled.
-
- File panelAssist.c has 3 routines that might be handy - one to swap panels, one
- to implement command+number keys as an alternative to clicking on a tab and one
- to implement command+Tab or control-tab to cycle through the tabs.
-
- If you have a situation where an entire panel should be disabled, disable each
- of the controls on the panel.
-
- The file cdefDemo.c shows how to use a "Tab Panel", but here is a brief list.
-
- 1. Include the files panelAssist.c/panelAssist.h in your project.
-
- 2. Define a dialog resource and DITL that contains just 3 controls "OK",
- "Cancel" and the TabPanel control as items 1-3.
-
- 3. Define a 'DITL' resource for each tab panel. Number them successively,
- starting with DLOGID+1.
-
- 4. Study the code in cdefDemo.c. That example places the OK & Cancel buttons
- outside the panel and saves all control values to a temp area before switching
- to another panel.
-
- 5. When Modal dialog informs your program that a Tab was clicked, do the
- following:
-
- - get the value of the tab control.
- - save the values of the control on the current panel.
- - call panelSwap with the new tab value to change panels.
- (this uses CountDITL, ShortenDITL and AppendDITL)
- - restore the values of the controls on the new panel.
-
- 6. If you want to use command+number keys to switch panels, call panelCmdKey()
- from your dialog filter routine whenever a keyboard event occurs with the
- command key down - obviously, this is only good for 10 or fewer tabs.
-
- To use command+tab or control-tab to rotate through tab panels, call
- panelCmdTab().
-
- --------------------------------------------------------------------------------
- Revision History:
- --------------------------------------------------------------------------------
-
- v1.2 September 1994
-
- - removed bogus UpdtDialog() call from demoCDEF.c - could
- cause a crash and wasn't needed.
- - minor fix to dimText.c.
- - fixed multiple monitor color problems in CDEFs that
- do not use offScreen drawing (3D Buttons, Popup,
- Tab Panel, Progress Bars & Group Box).
- - reworked some of the common routines for CDEFs in
- source folder "cdef Common".
- - finally got around to checking the controls in a window
- as opposed to a dialog. Lots of minor tweaks to make
- things work correctly with FindControl & TrackControl.
- Details follow.
- - many enhancements to the demoCDEF program to show:
- : disabled Group Boxes
- : Fractional increment in Spinner controls
- : "Live" display of control values for Sliders
- : Reset of DateTime controls to current time.
- : Linking of a Spinner control to Progress bar.
-
- Spinner
- -------
-
- ** MAJOR CHANGE **
-
- - the meaning of the refCon field has changed:
- LOWORD is the increment value to use
- HIWORD is the DITL item number to update
-
- The refCon value is only checked when the control is first
- initialized. The HIWORD is only honored if the controlOwner
- is a dialog window.
-
- - Spinner control has a new variation to get "3D" arrows.
- Use varCode 2 for this. 3D arrows are colored as are
- system scroll bars with cTingeLight & cTingeDark.
-
- - Spinner control now behaves correctly with TrackControl.
- Part codes returned are :
- 2 = decrease value
- 3 = increase value
-
- - it is now possible to have a spinner control that adjusts
- by a fractional value. This requires some special code in
- your program (after all, the contrlValue field is a short).
- See demoCDEF.c for an example.
-
- To do this, a struct is provided to let you store userData
- in the control's internal contrlData field - which is used
- by the control. See jimsCDEF.h for the struct.
- Tab Panel
- ---------
- - Tab Panel improved to handle multiple panels of tabs.
- It defaults to 4 tabs per panel, with a maximum of 5
- panels. Variation code 2 added to force a single panel.
- Variation code 1 will force System font.
- - added panelCmdTab() to panelAssist.c to allow cmd-Tab or
- cntl-Tab to cycle through the tabs.
- Sliders
- -------
- - Slider controls now behave correctly with Find/Track Control
- and will call an actionProc from SetCtlAction() if set.
- Part codes returned are :
- 1 = "thumb" adjusted value
- 2 = value was decreased
- 3 = value was increased
-
- - Slider controls : change in variation codes :
- 1 is now for "unfilled scale"
- 2 is now for "3D" effect
-
- Date & Time
- -----------
- - DateTime control values were changed to indicate what
- digits are currently hilited. FindControl part codes
- returned are:
- 2 - Hours
- 3 - Minutes
- 4 - AM/PM
- 5 - TimeUp (never as control value)
- 6 - TimeDown (never as control value)
-
- 7 - date 1 (per control panel)
- 8 - date 2
- 9 - date 3
- 10 - DateUp (never as control value)
- 11 - DateDown (never as control value)
-
- - DateTime control now has 2 "pseudo" variation codes:
- : if control Max is non-zero, 24 hour time is forced.
- : if control Min is non-zero, use 3D effect for arrows
- & text as with the Spinner control.
- Popup Menu
- ----------
- - Popup Menu control now recognizes variation 2 for 3D
- effects as in Group Boxes, Sliders and Spinner control.
-
- - as with Apple's CDEF 63, call TrackControl with the last
- parameter set to -1 to use this control in a regular
- window.
- Group Box
- ---------
- - now will disable and draw in gray.
-
- --------------------------------------------------------------------------------
-
- v1.1 August 1994 - added Tab Panel CDEF to collection (see description
- above).
- - all CDEF's use "embossed" text if used on a non-
- white background.
- - DateTime control now uses a title if supplied in
- control template.
- - PopUpMenu control draws color title per 'cctb'
- rather than 'mctb' and will "emboss" as with others.
- When the menu is "popped", the title colors are the
- same as the inverted menu item, rather than 'cctb'.
- colors. IMHO, this looks better.
- - Fixed a PenSize problem with 3D Buttons in Alerts
- with no 'actb' resource.
- - slider controls corrected to use proper gray when
- inactive.
- - slider controls now respond to clicks in the scale
- portion of the control.
- - variation 1 (was gray thumb) in slider controls now
- draws a "3D" version of the control. Shadow color
- is cTingeLight from 'cctb'.
- - removed a MAJOR memory leak in the slider controls.
- - Added a "barberpole" variation to the ProgressBar.
-
- - completely rewrote demo program to use the TabPanel
- control.
-
- --------------------------------------------------------------------------------
-
- v1.01 July 1994 - 3D Buttons now supports multi-line titles
- - GroupBox uses Control Max instead of RefCon for
- true height of box (templates must be changed).
- - both slider controls have a correction to tracking
- logic when mouse is moved past end of slider. Now,
- tracking will not resume until mouse is moved back
- to the thumb.
-
- --------------------------------------------------------------------------------
-
- v1.0 June 1994 - first distribution
-